What tweets got the most attention. frequency of tweets posted on a topic

library(rtweet)
library(ggplot2)
library(tidyr)
library(dplyr)
library(tidytext)
library(stringr)
library(scales)
library(readr)
library(lubridate)
library(vader)
library(topicmodels)
library(quanteda)
library(lubridate)
library(zoo)
library(plotly)

origop <- options("httr_oauth_cache")
options(httr_oauth_cache = TRUE)

api_key <- "5PgtS7ljq5ZbBoXnemU5qHe62"
api_secret <- "M44LeduQ4zoyDxQIkAFjeIJrpDhWnb5xASDvhahTlrAvOhN7fx"
access_token <- "743029724750942208-JLEp26XrjwvQ1CPJUXwvdUMLka82cgx"
access_secret <- "XRMeMBaOgQy2BC1Bd9iJARfMIyK40VKyII1ZRcf9nS0qd"
token <- create_token(
  app = "KyleResearchApp",
  consumer_key = api_key,
  consumer_secret = api_secret,
  access_token = access_token,
  access_secret = access_secret
)
media_agency_df <- get_timeline("News24", n = 3200)
media_agency_df <- media_agency_df %>% 
  mutate(rbind(rtweet::get_timeline("eNCA", n = 3200))) %>% 
  mutate(rbind(rtweet::get_timeline("ewnupdates", n = 3200))) %>% 
  mutate(rbind(rtweet::get_timeline("TimesLive", n = 3200))) %>% 
  mutate(rbind(rtweet::get_timeline("SABCNews", n = 3200)))

write_as_csv(media_agency_df, "data_in/media_agency_tweets")
media_agency_df <- read_csv("data_in/media_agency_tweets.csv")

media_agency_df <- media_agency_df[ , colSums(is.na(media_agency_df)) < nrow(media_agency_df)]

Comparing Tweet Archives

ggplot(media_agency_df, aes(x = created_at, fill = screen_name)) +
  geom_histogram(position = "identity", bins = 20, show.legend = FALSE) +
  facet_wrap(~screen_name, ncol = 1)
#tidy df and unnest
tidy_covid_media_df <- media_agency_df %>% 
  filter(str_detect(text, fixed(covid_dictionary, ignore_case = TRUE))) %>%
  filter(!str_detect(text, "^RT")) %>%
  mutate(text = gsub(" ?(f|ht)tp(s?)://(.*)[.][a-z]+", "", text)) %>%
  unnest_tokens(word, text, token = "tweets") %>% 
  filter(!word %in% stop_words$word,
         !word %in% str_remove_all(stop_words$word, "'"),
         str_detect(word, "[a-z]"),
         !(word =="sabcnews" |
             word =="enca" |
             word =="https" |
             word =="dstv" |
             word =="sabckzn" |
             word =="anc" |
             word =="south" |
             word =="africa" |
             word =="dstv403" |
             word =="t.co" |
             word =="itus" |
             word =="rt" |
             word =="amp"))
longer object length is not a multiple of shorter object lengthUsing `to_lower = TRUE` with `token = 'tweets'` may not preserve URLs.
#calculate a frequency for each person and word
frequency <- tidy_covid_media_df %>% 
  group_by(screen_name) %>% 
  count(word, sort = TRUE) %>% 
  left_join(tidy_covid_media_df %>% 
              group_by(screen_name) %>% 
              summarise(total = n())) %>%
  mutate(freq = n/total)
Joining, by = "screen_name"
vader_df <- vader_df(media_agency_df$text)
write_as_csv(vader_df, "data_in/vader_covid_df")

vader_df <- read_csv("data_in/vader_df.csv")
vader_covid_df <- read_csv("data_in/vader_covid_df.csv")
vader_df <- vader_df %>% mutate("X1" = row_number())
sentimentr_df <- read_csv("data_in/sentimentr_data.csv")
media_vader_df <- media_agency_df %>% left_join(vader_df, by = "X1")

#sentiment
ggplot(data=media_vader_df, aes(x=created_at, y=rollmean(compound, 30,  na.pad=TRUE))) +
       geom_line(color="pink", size=.5)+
  geom_smooth() +
  theme_minimal()+
  facet_wrap(~screen_name) +
  scale_y_continuous(expand = c(0,0), breaks = c(-0.4,-0.2,0,0.2,0.4)) +
  ylim(c(-0.4, 0.4))

#sentiment
ggplot(data=media_vader_df, aes(x=created_at, fill = screen_name)) +
  stat_smooth(media_vader_df %>% filter(screen_name == "News24"), mapping =  aes(y = mean(compound)))+
  stat_smooth(media_vader_df %>% filter(screen_name == "ewnupdates"), mapping =  aes(y = compound))+
  stat_smooth(media_vader_df %>% filter(screen_name == "eNCA"), mapping =  aes(y = compound))+
  stat_smooth(media_vader_df %>% filter(screen_name == "SABCNews"), mapping =  aes(y = compound))+
  stat_smooth(media_vader_df %>% filter(screen_name == "TimesLIVE"), mapping =  aes(y = compound))+
  theme_minimal()+
  scale_y_continuous(expand = c(0,0), breaks = c(-0.1, 0)) 
  

ggplot(data=media_vader_df, aes(x=created_at, colour = screen_name)) +
  geom_line(media_vader_df %>% filter(screen_name == "News24"), mapping =  aes(y = rollmean(compound, k = 30, na.pad = TRUE)))+
  geom_line(media_vader_df %>% filter(screen_name == "ewnupdates"), mapping = aes(y = rollmean(compound, k = 30, na.pad = TRUE)))+
  geom_line(media_vader_df %>% filter(screen_name == "eNCA"), mapping = aes(y = rollmean(compound, k = 30, na.pad = TRUE)))+
  geom_line(media_vader_df %>% filter(screen_name == "SABCNews"), mapping = aes(y = rollmean(compound, k = 30, na.pad = TRUE)))+
  geom_line(media_vader_df %>% filter(screen_name == "TimesLIVE"), mapping = aes(y = rollmean(compound, k = 30, na.pad = TRUE)))+
  theme_minimal()+
  scale_y_continuous(expand = c(0,0)) 

ggplot(media_vader_df %>% arrange(compound) %>% mutate(X1 = factor(X1, levels = X1)), aes(x=X1)) +
  geom_point(mapping =  aes(y = compound)) +
  theme_minimal()+
  scale_y_continuous(expand = c(0,0)) 


install.packages("ldatuning")


install.packages("devtools")
devtools::install_github("nikita-moor/ldatuning")


library("ldatuning")


library("topicmodels")
data("AssociatedPress", package="topicmodels")
dtm <- AssociatedPress[1:10, ]


result <- FindTopicsNumber(
  tidy_matrix,
  topics = seq(from = 2, to = 15, by = 1),
  metrics = c("Griffiths2004", "CaoJuan2009", "Arun2010", "Deveaud2014"),
  method = "Gibbs",
  control = list(seed = 77),
  mc.cores = 2L,
  verbose = TRUE
)


##  fit models... done.
##  calculate metrics:
##   Griffiths2004... done.
##   CaoJuan2009... done.
##   Arun2010... done.
##   Deveaud2014... done.


FindTopicsNumber_plot(result)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpXaGF0IHR3ZWV0cyBnb3QgdGhlIG1vc3QgYXR0ZW50aW9uLg0KZnJlcXVlbmN5IG9mIHR3ZWV0cyBwb3N0ZWQgb24gYSB0b3BpYw0KDQoNCmBgYHtyfQ0KbGlicmFyeShydHdlZXQpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodGlkeXRleHQpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkodmFkZXIpDQpsaWJyYXJ5KHRvcGljbW9kZWxzKQ0KbGlicmFyeShxdWFudGVkYSkNCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeSh6b28pDQpsaWJyYXJ5KHBsb3RseSkNCg0Kb3JpZ29wIDwtIG9wdGlvbnMoImh0dHJfb2F1dGhfY2FjaGUiKQ0Kb3B0aW9ucyhodHRyX29hdXRoX2NhY2hlID0gVFJVRSkNCg0KYXBpX2tleSA8LSAiNVBndFM3bGpxNVpiQm9YbmVtVTVxSGU2MiINCmFwaV9zZWNyZXQgPC0gIk00NExlZHVRNHpveUR4UUlrQUZqZUlKcnBEaFduYjV4QVNEdmhhaFRsckF2T2hON2Z4Ig0KYWNjZXNzX3Rva2VuIDwtICI3NDMwMjk3MjQ3NTA5NDIyMDgtSkxFcDI2WHJqd3ZRMUNQSlVYd3ZkVU1Ma2E4MmNneCINCmFjY2Vzc19zZWNyZXQgPC0gIlhSTWVNQmFPZ1F5MkJDMUJkOWlKQVJmTUl5SzQwVkt5SUkxWlJjZjluUzBxZCINCnRva2VuIDwtIGNyZWF0ZV90b2tlbigNCiAgYXBwID0gIkt5bGVSZXNlYXJjaEFwcCIsDQogIGNvbnN1bWVyX2tleSA9IGFwaV9rZXksDQogIGNvbnN1bWVyX3NlY3JldCA9IGFwaV9zZWNyZXQsDQogIGFjY2Vzc190b2tlbiA9IGFjY2Vzc190b2tlbiwNCiAgYWNjZXNzX3NlY3JldCA9IGFjY2Vzc19zZWNyZXQNCikNCmBgYA0KDQpgYGB7cn0NCm1lZGlhX2FnZW5jeV9kZiA8LSBnZXRfdGltZWxpbmUoIk5ld3MyNCIsIG4gPSAzMjAwKQ0KbWVkaWFfYWdlbmN5X2RmIDwtIG1lZGlhX2FnZW5jeV9kZiAlPiUgDQogIG11dGF0ZShyYmluZChydHdlZXQ6OmdldF90aW1lbGluZSgiZU5DQSIsIG4gPSAzMjAwKSkpICU+JSANCiAgbXV0YXRlKHJiaW5kKHJ0d2VldDo6Z2V0X3RpbWVsaW5lKCJld251cGRhdGVzIiwgbiA9IDMyMDApKSkgJT4lIA0KICBtdXRhdGUocmJpbmQocnR3ZWV0OjpnZXRfdGltZWxpbmUoIlRpbWVzTGl2ZSIsIG4gPSAzMjAwKSkpICU+JSANCiAgbXV0YXRlKHJiaW5kKHJ0d2VldDo6Z2V0X3RpbWVsaW5lKCJTQUJDTmV3cyIsIG4gPSAzMjAwKSkpDQoNCndyaXRlX2FzX2NzdihtZWRpYV9hZ2VuY3lfZGYsICJkYXRhX2luL21lZGlhX2FnZW5jeV90d2VldHMiKQ0KbWVkaWFfYWdlbmN5X2RmIDwtIHJlYWRfY3N2KCJkYXRhX2luL21lZGlhX2FnZW5jeV90d2VldHMuY3N2IikNCg0KbWVkaWFfYWdlbmN5X2RmIDwtIG1lZGlhX2FnZW5jeV9kZlsgLCBjb2xTdW1zKGlzLm5hKG1lZGlhX2FnZW5jeV9kZikpIDwgbnJvdyhtZWRpYV9hZ2VuY3lfZGYpXQ0KYGBgDQoNCg0KIyBDb21wYXJpbmcgVHdlZXQgQXJjaGl2ZXMNCg0KDQpgYGB7cn0NCmdncGxvdChtZWRpYV9hZ2VuY3lfZGYsIGFlcyh4ID0gY3JlYXRlZF9hdCwgZmlsbCA9IHNjcmVlbl9uYW1lKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShwb3NpdGlvbiA9ICJpZGVudGl0eSIsIGJpbnMgPSAyMCwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBmYWNldF93cmFwKH5zY3JlZW5fbmFtZSwgbmNvbCA9IDEpDQpgYGANCg0KYGBge3IgQ2xlYW4gdXB9DQoNCmNvdmlkX2RpY3Rpb25hcnkgPC0gYygiaGVyZCIsICJpbW11bml0eSIsICJpbmN1YmF0aW9uIiwgImpvYiIsICJsb3NzIiwgIktpdHMiLCAibG9ja2Rvd24iLCAibWFzayIsICJOOTUiLCAib3V0YnJlYWsiLCAicGFuZGVtaWMiLCAicXVhcmFudGluZSIsICJyZWNvdmVyeSIsICJzYW5pdGlzZXIiLCAidHJhbnNtaXNzaW9uIiwgIlVuZGVybHlpbmciLCAiY29uZGl0aW9ucyIsICJWZW50aWxhdG9ycyIsICJXSE8iLCAieGVub3Bob2JpYSIsICJ5b3VUdWJlIiwgInpvb25vdGljIiwgInN0YXktYXQtaG9tZSIsICJjb3ZpZCIsICJjb3JvbmF2aXJ1cyIsICJoeXJkb3h5Y2hsb3JvcXVpbmUiLCAiYXN5bXB0b21hdGljIiwgImZyb250bGluZSIsICJ2aXJ1cyIsICJzZWxmLWlzb2xhdGlvbiIsICJkaXNpbmZlY3RhbnQiLCAic2hlbHRlci1pbi1wbGFjZSIsICJtYXNrcyIsICJTQVJTLUNvVi0yIiwgIklDVSIsICJjb3JvbmEiLCAicmVvcGVuIiwgImRpc3RhbmNpbmciLCAiY292ZXJpbmciLCAiZnVybG91Z2giLCAidHJhY2VyIiwgImVhc2luZyIsICJyZW1kZXNpdmlyIiwgIm1haWwtaW4iLCAiaG9ybmV0IiwgImFudGlib2R5IiwgImluLXBlcnNvbiIsICJkZWZ1bmQiLCAicmFjaXNtIiwgImxvb3RpbmciLCAibG9vdCIsICJyZW9wZW4iLCAidHdvLW1ldHJlIiwgInBhbmRlbWljIiwgImxvb3RlciIsICJkaXN0YW5jaW5nIiwgImRleGFtZXRoYXNvbmUiLCAicmFjaWFsIiwgInZhY2NpbmUiKQ0KDQojSlVTVCB0aWR5DQptZWRpYV9hZ2VuY3lfZGYgPC0gbWVkaWFfYWdlbmN5X2RmICU+JSANCiAgbXV0YXRlKHRleHQgPSBnc3ViKCIgPyhmfGh0KXRwKHM/KTovLyguKilbLl1bYS16XSsiLCAiIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiJmFtcCIsICIiLCB0ZXh0KSwNCiAgICAgICAgIHRleHQgPSBnc3ViKCIoUlR8dmlhKSgoPzpcXGJcXFcqQFxcdyspKykiLCAiIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiQFxcdysiLCAiIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiW1s6cHVuY3Q6XV0iLCAiIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiW1s6ZGlnaXQ6XV0iLCAiIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiaHR0cFxcdysiLCAiIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiWyBcdF17Mix9IiwgIiIsIHRleHQpLA0KICAgICAgICAgdGV4dCA9IGdzdWIoIl5cXHMrfFxccyskIiwgIiIsIHRleHQpLA0KICAgICAgICAgdGV4dCA9IGdzdWIoImVuY2EiLCAiIiwgdGV4dCksDQogICAgICAgICB0ZXh0ID0gZ3N1YigiZHN0diIsICIiLCB0ZXh0KSwNCiAgICAgICAgIHRleHQgPSBnc3ViKCJzYWJjbmV3cyIsICIiLCB0ZXh0KSwNCiAgICAgICAgIHRleHQgPSBnc3ViKCImYW1wIiwgIiIsIHRleHQpKSAlPiUgDQogIG11dGF0ZSh0ZXh0ID0gc3RyX3JlcGxhY2VfYWxsKHRleHQsIiAiLCIgIiksDQogICAgICAgICB0ZXh0ID0gc3RyX3JlcGxhY2VfYWxsKHRleHQsIlJUIEBbYS16LEEtWl0qOiAiLCIgIiksDQogICAgICAgICB0ZXh0ID0gc3RyX3JlcGxhY2VfYWxsKHRleHQsIiNbYS16LEEtWl0qIiwiICIpLA0KICAgICAgICAgdGV4dCA9IHN0cl9yZXBsYWNlX2FsbCh0ZXh0LCJAW2EteixBLVpdKiIsIiAiKSkNCiAgDQojdGlkeSBkZiBhbmQgdW5uZXN0DQp0aWR5X2NvdmlkX21lZGlhX2RmIDwtIG1lZGlhX2FnZW5jeV9kZiAlPiUgDQogIGZpbHRlcihzdHJfZGV0ZWN0KHRleHQsIGZpeGVkKGNvdmlkX2RpY3Rpb25hcnksIGlnbm9yZV9jYXNlID0gVFJVRSkpKSAlPiUNCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KHRleHQsICJeUlQiKSkgJT4lDQogIG11dGF0ZSh0ZXh0ID0gZ3N1YigiID8oZnxodCl0cChzPyk6Ly8oLiopWy5dW2Etel0rIiwgIiIsIHRleHQpKSAlPiUNCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCB0ZXh0LCB0b2tlbiA9ICJ0d2VldHMiKSAlPiUgDQogIGZpbHRlcighd29yZCAlaW4lIHN0b3Bfd29yZHMkd29yZCwNCiAgICAgICAgICF3b3JkICVpbiUgc3RyX3JlbW92ZV9hbGwoc3RvcF93b3JkcyR3b3JkLCAiJyIpLA0KICAgICAgICAgc3RyX2RldGVjdCh3b3JkLCAiW2Etel0iKSwNCiAgICAgICAgICEod29yZCA9PSJzYWJjbmV3cyIgfA0KICAgICAgICAgICAgIHdvcmQgPT0iZW5jYSIgfA0KICAgICAgICAgICAgIHdvcmQgPT0iaHR0cHMiIHwNCiAgICAgICAgICAgICB3b3JkID09ImRzdHYiIHwNCiAgICAgICAgICAgICB3b3JkID09InNhYmNrem4iIHwNCiAgICAgICAgICAgICB3b3JkID09ImFuYyIgfA0KICAgICAgICAgICAgIHdvcmQgPT0ic291dGgiIHwNCiAgICAgICAgICAgICB3b3JkID09ImFmcmljYSIgfA0KICAgICAgICAgICAgIHdvcmQgPT0iZHN0djQwMyIgfA0KICAgICAgICAgICAgIHdvcmQgPT0idC5jbyIgfA0KICAgICAgICAgICAgIHdvcmQgPT0iaXR1cyIgfA0KICAgICAgICAgICAgIHdvcmQgPT0icnQiIHwNCiAgICAgICAgICAgICB3b3JkID09ImFtcCIpKQ0KDQpgYGANCg0KYGBge3IgdGYtaWRmfQ0KI3RvcCB3b3Jkcw0KdG9wX3dvcmRzIDwtIHRpZHlfY292aWRfbWVkaWFfZGYgJT4lIA0KICBhbnRpX2pvaW4oc3RvcF93b3JkcykgJT4lIA0KICBjb3VudCh3b3JkKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhuKSkNCnRvcF93b3JkcyAlPiUgDQogIHNsaWNlKDE6MjApICU+JSANCiAgZ2dwbG90KGFlcyhyZW9yZGVyKHdvcmQsIC1uKSwgbiwgZmlsbCA9IHdvcmQpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDYwLCBoanVzdCA9IDEsIHNpemUgPSAxMyksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDE4KQ0KICAgICkgKw0KICB5bGFiKCJGcmVxdWVuY3kiKSArDQogIHhsYWIgKCIiKSArDQogIGdndGl0bGUoIk1vc3QgZnJlcXVlbnQgbWVkaWEgYWdlbmN5IHR3ZWV0cyIpICsNCiAgZ3VpZGVzKGZpbGw9RkFMU0UpDQoNCiN0Zi1pZGYNCnRpZHlfY292aWRfbWVkaWFfdGZpZGYgPC0gdGlkeV9jb3ZpZF9tZWRpYV9kZiAlPiUgDQogIHNlbGVjdChjcmVhdGVkX2F0LCB3b3JkKSAlPiUgDQogIGNvdW50KHdvcmQsIGNyZWF0ZWRfYXQpICU+JSANCiAgYmluZF90Zl9pZGYod29yZCwgY3JlYXRlZF9hdCwgbikNCg0KI3RvcF90ZmlkZg0KdGlkeV9jb3ZpZF9tZWRpYV90ZmlkZiAlPiUgDQogIHNsaWNlKC0oMTo1ODIpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyh0Zl9pZGYpKQ0KDQoNCiNjYWxjdWxhdGUgYSBmcmVxdWVuY3kgZm9yIGVhY2ggcGVyc29uIGFuZCB3b3JkDQpmcmVxdWVuY3kgPC0gdGlkeV9jb3ZpZF9tZWRpYV9kZiAlPiUgDQogIGdyb3VwX2J5KHNjcmVlbl9uYW1lKSAlPiUgDQogIGNvdW50KHdvcmQsIHNvcnQgPSBUUlVFKSAlPiUgDQogIGxlZnRfam9pbih0aWR5X2NvdmlkX21lZGlhX2RmICU+JSANCiAgICAgICAgICAgICAgZ3JvdXBfYnkoc2NyZWVuX25hbWUpICU+JSANCiAgICAgICAgICAgICAgc3VtbWFyaXNlKHRvdGFsID0gbigpKSkgJT4lDQogIG11dGF0ZShmcmVxID0gbi90b3RhbCkNCg0KI3Bsb3QgdGhvc2UgZnJlcXVlbmNpZXMgb24gdGhlIHgtIGFuZCB5LWF4ZXMgDQpmcmVxdWVuY3kgPC0gZnJlcXVlbmN5ICU+JSANCiAgc2VsZWN0KHNjcmVlbl9uYW1lLCB3b3JkLCBmcmVxKSAlPiUgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzY3JlZW5fbmFtZSwgdmFsdWVzX2Zyb20gPSBmcmVxKQ0KDQojeWVhcmx5IA0KYGBgDQoNCmBgYHtyIFZBREVSfQ0KdmFkZXJfZGYgPC0gdmFkZXJfZGYobWVkaWFfYWdlbmN5X2RmJHRleHQpDQp3cml0ZV9hc19jc3YodmFkZXJfZGYsICJkYXRhX2luL3ZhZGVyX2NvdmlkX2RmIikNCg0KdmFkZXJfZGYgPC0gcmVhZF9jc3YoImRhdGFfaW4vdmFkZXJfZGYuY3N2IikNCnZhZGVyX2NvdmlkX2RmIDwtIHJlYWRfY3N2KCJkYXRhX2luL3ZhZGVyX2NvdmlkX2RmLmNzdiIpDQp2YWRlcl9kZiA8LSB2YWRlcl9kZiAlPiUgbXV0YXRlKCJYMSIgPSByb3dfbnVtYmVyKCkpDQpzZW50aW1lbnRyX2RmIDwtIHJlYWRfY3N2KCJkYXRhX2luL3NlbnRpbWVudHJfZGF0YS5jc3YiKQ0KbWVkaWFfdmFkZXJfZGYgPC0gbWVkaWFfYWdlbmN5X2RmICU+JSBsZWZ0X2pvaW4odmFkZXJfZGYsIGJ5ID0gIlgxIikNCg0KI3NlbnRpbWVudA0KZ2dwbG90KGRhdGE9bWVkaWFfdmFkZXJfZGYsIGFlcyh4PWNyZWF0ZWRfYXQsIHk9cm9sbG1lYW4oY29tcG91bmQsIDMwLCAgbmEucGFkPVRSVUUpKSkgKw0KICAgICAgIGdlb21fbGluZShjb2xvcj0icGluayIsIHNpemU9LjUpKw0KICBnZW9tX3Ntb290aCgpICsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBmYWNldF93cmFwKH5zY3JlZW5fbmFtZSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApLCBicmVha3MgPSBjKC0wLjQsLTAuMiwwLDAuMiwwLjQpKSArDQogIHlsaW0oYygtMC40LCAwLjQpKQ0KDQojc2VudGltZW50DQpnZ3Bsb3QoZGF0YT1tZWRpYV92YWRlcl9kZiwgYWVzKHg9Y3JlYXRlZF9hdCwgZmlsbCA9IHNjcmVlbl9uYW1lKSkgKw0KICBzdGF0X3Ntb290aChtZWRpYV92YWRlcl9kZiAlPiUgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJOZXdzMjQiKSwgbWFwcGluZyA9ICBhZXMoeSA9IG1lYW4oY29tcG91bmQpKSkrDQogIHN0YXRfc21vb3RoKG1lZGlhX3ZhZGVyX2RmICU+JSBmaWx0ZXIoc2NyZWVuX25hbWUgPT0gImV3bnVwZGF0ZXMiKSwgbWFwcGluZyA9ICBhZXMoeSA9IGNvbXBvdW5kKSkrDQogIHN0YXRfc21vb3RoKG1lZGlhX3ZhZGVyX2RmICU+JSBmaWx0ZXIoc2NyZWVuX25hbWUgPT0gImVOQ0EiKSwgbWFwcGluZyA9ICBhZXMoeSA9IGNvbXBvdW5kKSkrDQogIHN0YXRfc21vb3RoKG1lZGlhX3ZhZGVyX2RmICU+JSBmaWx0ZXIoc2NyZWVuX25hbWUgPT0gIlNBQkNOZXdzIiksIG1hcHBpbmcgPSAgYWVzKHkgPSBjb21wb3VuZCkpKw0KICBzdGF0X3Ntb290aChtZWRpYV92YWRlcl9kZiAlPiUgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJUaW1lc0xJVkUiKSwgbWFwcGluZyA9ICBhZXMoeSA9IGNvbXBvdW5kKSkrDQogIHRoZW1lX21pbmltYWwoKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSwgYnJlYWtzID0gYygtMC4xLCAwKSkgDQogIA0KDQpnZ3Bsb3QoZGF0YT1tZWRpYV92YWRlcl9kZiwgYWVzKHg9Y3JlYXRlZF9hdCwgY29sb3VyID0gc2NyZWVuX25hbWUpKSArDQogIGdlb21fbGluZShtZWRpYV92YWRlcl9kZiAlPiUgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJOZXdzMjQiKSwgbWFwcGluZyA9ICBhZXMoeSA9IHJvbGxtZWFuKGNvbXBvdW5kLCBrID0gMzAsIG5hLnBhZCA9IFRSVUUpKSkrDQogIGdlb21fbGluZShtZWRpYV92YWRlcl9kZiAlPiUgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJld251cGRhdGVzIiksIG1hcHBpbmcgPSBhZXMoeSA9IHJvbGxtZWFuKGNvbXBvdW5kLCBrID0gMzAsIG5hLnBhZCA9IFRSVUUpKSkrDQogIGdlb21fbGluZShtZWRpYV92YWRlcl9kZiAlPiUgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJlTkNBIiksIG1hcHBpbmcgPSBhZXMoeSA9IHJvbGxtZWFuKGNvbXBvdW5kLCBrID0gMzAsIG5hLnBhZCA9IFRSVUUpKSkrDQogIGdlb21fbGluZShtZWRpYV92YWRlcl9kZiAlPiUgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJTQUJDTmV3cyIpLCBtYXBwaW5nID0gYWVzKHkgPSByb2xsbWVhbihjb21wb3VuZCwgayA9IDMwLCBuYS5wYWQgPSBUUlVFKSkpKw0KICBnZW9tX2xpbmUobWVkaWFfdmFkZXJfZGYgJT4lIGZpbHRlcihzY3JlZW5fbmFtZSA9PSAiVGltZXNMSVZFIiksIG1hcHBpbmcgPSBhZXMoeSA9IHJvbGxtZWFuKGNvbXBvdW5kLCBrID0gMzAsIG5hLnBhZCA9IFRSVUUpKSkrDQogIHRoZW1lX21pbmltYWwoKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkgDQoNCmdncGxvdChtZWRpYV92YWRlcl9kZiAlPiUgYXJyYW5nZShjb21wb3VuZCkgJT4lIG11dGF0ZShYMSA9IGZhY3RvcihYMSwgbGV2ZWxzID0gWDEpKSwgYWVzKHg9WDEpKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9ICBhZXMoeSA9IGNvbXBvdW5kKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCkpIA0KDQpgYGANCg0KYGBge3IgSW50ZXJhY3Rpb25zfQ0KbWVkaWFfdmFkZXJfZGYgJT4lIHNlbGVjdChmYXZvcml0ZV9jb3VudCwgcmV0d2VldF9jb3VudCkgJT4lIG11dGF0ZShmYXZvcml0ZV9jb3VudCArIHJldHdlZXRfY291bnQpDQptZWRpYV92YWRlcl9kZiAlPiUgbXV0YXRlKGNyZWF0ZWRfYXQgPSBhcy5EYXRlKGNyZWF0ZWRfYXQpKSAlPiUgIGdyb3VwX2J5KGNyZWF0ZWRfYXQpICU+JSBtdXRhdGUoc3VtID0gc3VtKGZhdm9yaXRlX2NvdW50ICsgcmV0d2VldF9jb3VudCkpIA0KIG1lZGlhX3ZhZGVyX2RmICU+JSBtdXRhdGUoY3JlYXRlZF9hdCA9IGFzLkRhdGUoY3JlYXRlZF9hdCkpICU+JSAgZ3JvdXBfYnkoY3JlYXRlZF9hdCwgc2NyZWVuX25hbWUpICU+JSBtdXRhdGUocmV0d2VldF9kYWlseSA9IHN1bShyZXR3ZWV0X2NvdW50KSwgZmF2b3JpdGVfZGFpbHkgPSBzdW0oZmF2b3JpdGVfY291bnQpKSAlPiUgdW5ncm91cCgpDQoNCnBsb3QgPC0gbWVkaWFfdmFkZXJfZGYgJT4lIG11dGF0ZShjcmVhdGVkX2F0ID0gYXMuRGF0ZShjcmVhdGVkX2F0KSkgJT4lICBncm91cF9ieShjcmVhdGVkX2F0KSAlPiUgbXV0YXRlKHJldHdlZXRfZGFpbHkgPSBzdW0ocmV0d2VldF9jb3VudCksIGZhdm9yaXRlX2RhaWx5ID0gc3VtKGZhdm9yaXRlX2NvdW50KSwgc3VtID0gc3VtKGZhdm9yaXRlX2NvdW50ICsgcmV0d2VldF9jb3VudCkpICU+JSANCiAgZ2dwbG90KGFlcyhjcmVhdGVkX2F0KSkgKw0KICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IDAsIHltYXggPSByZXR3ZWV0X2RhaWx5LCB5ID0gc3VtLCBmaWxsID0gImJsdWUiKSkNCiAgDQpnZ3Bsb3RseShwbG90KQ0KDQpwbG90IDwtIG1lZGlhX3ZhZGVyX2RmICU+JSBtdXRhdGUoY3JlYXRlZF9hdCA9IGFzLkRhdGUoY3JlYXRlZF9hdCkpICU+JSAgZ3JvdXBfYnkoY3JlYXRlZF9hdCkgJT4lIG11dGF0ZShzdW0gPSBzdW0oZmF2b3JpdGVfY291bnQgKyByZXR3ZWV0X2NvdW50KSkgJT4lIA0KICBnZ3Bsb3QoYWVzKGNyZWF0ZWRfYXQsIHN1bSkpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSAwLCB5bWF4ID0gc3VtKSkgDQogIA0KZ2dwbG90bHkocGxvdCkNCg0KbWVkaWFfdmFkZXJfZGYgJT4lIA0KICAgZmlsdGVyKHNjcmVlbl9uYW1lID09ICJTQUJDTmV3cyIpICU+JSANCiAgc2xpY2VfbWF4KGZhdm9yaXRlX2NvdW50ICsgcmV0d2VldF9jb3VudCArIHF1b3RlZF9yZXR3ZWV0X2NvdW50KSANCg0KY2xhc3MobWVkaWFfdmFkZXJfZGYkY3JlYXRlZF9hdCkNCg0KIyB0b3AgdHdlZXRzDQojIGVOQ0EgQ2FsbCBmb3IgbWluaXN0ZXJzIG92ZXIgNjAgdG8gcmVzaWduIGh0dHBzOi8vdC5jby93bEVqSkdFcHVrDQojIGV3biBLWk4gYm95ICg1KSBnZXRzIGhvbWUgc2FmZWx5IGFmdGVyIHRheGkgZHJpdmVyIGtpY2tzIGhpbSBvdXQgZm9yIG5vdCBoYXZpbmcgZmFyZSBodHRwczovL3QuY28vdGZPOWF4b2RhciBodHRwczovL3QuY28veXgzWWpWOXZhbw0KIyBUaW1lc0xJVkUJRG8geW91IGFwcHJvdmUgb2YgRHVkdXphbmUgcnVubmluZyBmb3IgcHJlc2lkZW50PyBodHRwczovL3QuY28vaENEVlFHSFJXeQ0KIyBOZXdzMjQgQ29jYS1Db2xhIGxvc3QgJDQgYmlsbGlvbiBpbiBtYXJrZXQgdmFsdWUgYWZ0ZXIgQ3Jpc3RpYW5vIFJvbmFsZG8gc3VnZ2VzdGVkIHBlb3BsZSBkcmluayB3YXRlciBpbnN0ZWFkIHwgQEJJU291dGhBZnJpY2ENCiMgU0FCQ05ld3MgQlJFQUtJTkcgTkVXUzogS2luZyBvZiBFc3dhdGluaSBoYXMgZmxlZCBhbWlkIHB1YmxpYyB2aW9sZW5jZSBpbiB0aGUgY291bnRyeSBodHRwczovL3QuY28vMWp2OHZWQ3c5ZA0KYGBgDQoNCmBgYHtyIFRvcGljIE1vZGVsbGluZ30NCnRpZHlfbWF0cml4IDwtIHRpZHlfY292aWRfbWVkaWFfZGYgJT4lIGNvdW50KHNjcmVlbl9uYW1lLCB3b3JkKSAlPiUgY2FzdF9kZm0oc2NyZWVuX25hbWUsIHdvcmQsIG4pDQoNCm1lZGlhX2xkYSA8LSBMREEodGlkeV9tYXRyaXgsIGsgPSA1LCBjb250cm9sID0gbGlzdChzZWVkID0gMTIzNCkpDQoNCm1lZGlhX3RvcGljcyA8LSB0aWR5KG1lZGlhX2xkYSwgbWF0cml4ID0gImJldGEiKQ0KDQptZWRpYV90b3BfdGVybXMgPC0gbWVkaWFfdG9waWNzICU+JQ0KICBncm91cF9ieSh0b3BpYykgJT4lDQogIHNsaWNlX21heChiZXRhLCBuID0gMTApICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBhcnJhbmdlKHRvcGljLCAtYmV0YSkNCg0KbWVkaWFfdG9wX3Rlcm1zICU+JQ0KICBtdXRhdGUodGVybSA9IHJlb3JkZXJfd2l0aGluKHRlcm0sIGJldGEsIHRvcGljKSkgJT4lDQogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSB0ZXJtLCBuYW1lc19mcm9tID0gdG9waWMsIHZhbHVlc19mcm9tID0gYmV0YSkgJT4lDQogIHJlbmFtZSgiTmF0aW9ucyBBZGRyZXNzIiA9IDIsICJHZXR0aW5nIHZhY2NpbmF0ZWQgZm9yIHRoaXJkIHdhdmUiID0gMywgIkFubm91bmNlbWVudCBvZiB2YWNjaW5lIiA9IDQsICJDb3ZpZC0xOTogU291dGggQWZyaWNhIHVwZGF0ZSIgPSA1LCAiVmFjY2luYXRpb24gZGlzdHJpYnV0aW9ucyIgPSA2KSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKDIsMyw0LDUsNiksIG5hbWVzX3RvID0gInRvcGljIiwgdmFsdWVzX3RvID0gImJldGEiKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBnZ3Bsb3QoYWVzKGJldGEsIHRlcm0sIGZpbGwgPSBmYWN0b3IodG9waWMpKSkgKw0KICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGZhY2V0X3dyYXAofiB0b3BpYywgc2NhbGVzID0gImZyZWUiKSArDQogIHNjYWxlX3lfcmVvcmRlcmVkKCkNCmBgYA0KDQpgYGB7ciBHYXAgayBqdXN0aWZ5fQ0KDQppbnN0YWxsLnBhY2thZ2VzKCJsZGF0dW5pbmciKQ0KDQoNCmluc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikNCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1YigibmlraXRhLW1vb3IvbGRhdHVuaW5nIikNCg0KDQpsaWJyYXJ5KCJsZGF0dW5pbmciKQ0KDQoNCmxpYnJhcnkoInRvcGljbW9kZWxzIikNCmRhdGEoIkFzc29jaWF0ZWRQcmVzcyIsIHBhY2thZ2U9InRvcGljbW9kZWxzIikNCmR0bSA8LSBBc3NvY2lhdGVkUHJlc3NbMToxMCwgXQ0KDQoNCnJlc3VsdCA8LSBGaW5kVG9waWNzTnVtYmVyKA0KICB0aWR5X21hdHJpeCwNCiAgdG9waWNzID0gc2VxKGZyb20gPSAyLCB0byA9IDE1LCBieSA9IDEpLA0KICBtZXRyaWNzID0gYygiR3JpZmZpdGhzMjAwNCIsICJDYW9KdWFuMjAwOSIsICJBcnVuMjAxMCIsICJEZXZlYXVkMjAxNCIpLA0KICBtZXRob2QgPSAiR2liYnMiLA0KICBjb250cm9sID0gbGlzdChzZWVkID0gNzcpLA0KICBtYy5jb3JlcyA9IDJMLA0KICB2ZXJib3NlID0gVFJVRQ0KKQ0KDQoNCiMjICBmaXQgbW9kZWxzLi4uIGRvbmUuDQojIyAgY2FsY3VsYXRlIG1ldHJpY3M6DQojIyAgIEdyaWZmaXRoczIwMDQuLi4gZG9uZS4NCiMjICAgQ2FvSnVhbjIwMDkuLi4gZG9uZS4NCiMjICAgQXJ1bjIwMTAuLi4gZG9uZS4NCiMjICAgRGV2ZWF1ZDIwMTQuLi4gZG9uZS4NCg0KDQpGaW5kVG9waWNzTnVtYmVyX3Bsb3QocmVzdWx0KQ0KYGBgDQoNCg==